package com.system.seckillgoods.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.common.bean.SeckillActivity;
import com.system.common.bean.SeckillGoods;
import com.system.common.exception.ServiceException;
import com.system.common.service.ISeckillActivityService;
import com.system.common.service.ISeckillGoodsService;
import com.system.common.util.SYS;
import com.system.seckillgoods.mapper.SeckillActivityMapper;

import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Time;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@DubboService
@Service
public class SeckillActivityServiceImpl
        extends ServiceImpl<SeckillActivityMapper, SeckillActivity>
        implements ISeckillActivityService {


    @DubboReference
    private ISeckillGoodsService seckillGoodsService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public SeckillActivity getActivityById(Integer id) {
        return super.getById(id);
    }

    @Override
    public void addActivity(SeckillActivity activity) {
        super.save(activity);
    }

    @Override
    public void updateActivity(SeckillActivity activity) {
        SeckillActivity exist = super.getById(activity.getId());
        if (exist == null) throw new ServiceException("活动不存在");
        super.updateById(activity);
    }

    @Override
    public void deleteActivity(Integer id) {
        SeckillActivity activity = super.getById(id);
        if (activity == null) throw new ServiceException("活动不存在");
        activity.setIsdel(1);
        super.updateById(activity);
    }

    @Override
    public List<SeckillActivity> getActivityList() {
        LambdaQueryWrapper<SeckillActivity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SeckillActivity::getIsdel, 0);
        return super.list(wrapper);
    }

    @Override
    public IPage<SeckillActivity> getPage(SeckillActivity activity, Page<SeckillActivity> page) {
        LambdaQueryWrapper<SeckillActivity> queryWrapper = new LambdaQueryWrapper<>();
        if (activity != null && activity.getName() != null){
            queryWrapper.like(SeckillActivity::getName, activity.getName());
        }
        if (activity != null && activity.getStatus() != null){
            queryWrapper.eq(SeckillActivity::getStatus, activity.getStatus());
        }
        Page<SeckillActivity> resultPage = baseMapper.selectPage(page, queryWrapper);
        Date now = new Date();
        List<SeckillActivity> records = resultPage.getRecords();
        for (SeckillActivity act : records) {
            if(now.before(act.getStarttime())&&now.before(act.getEndtime())){
                act.setStatus(0);
            }
            if(now.after(act.getStarttime())&&now.before(act.getEndtime())){
                act.setStatus(1);
            }
            if(now.after(act.getEndtime())){
                act.setStatus(2);
            }
        }
        resultPage.setRecords(records);
        return resultPage;
    }

    @Override
    public boolean isActivityActive(Integer id) {
        SeckillActivity activity = super.getById(id);
        if (activity == null || activity.getIsdel() == 1) throw new ServiceException("活动不存在");
        Date now = new Date();
        return now.after(activity.getStarttime()) && now.before(activity.getEndtime());
    }



    @Override
public boolean startPreheat(Integer id){
    //参数id 秒杀活动id
    //redis中是否有这个活动。如果有，则已经开启
    String activity_redis_key = SYS.SK_PRE_ACTIVITY_KEY + id;
    if (redisTemplate.hasKey(activity_redis_key)){
        throw new ServiceException("活动已开启");
    }
    //获取数据库中的活动信息
    SeckillActivity activity = this.getById(id);
    if (activity == null || activity.getIsdel() == 1){
        throw new ServiceException("活动不存在");
    }
    if (activity.getStatus() != 0){
        throw new ServiceException("活动状态异常");
    }
    Date endTime = activity.getEndtime();
    Date startTime = activity.getStarttime();
    //活动结束时间毫秒数
    Long endTimeMillis = endTime.getTime();
    Long startTimeMillis = startTime.getTime();
    //当前时间毫秒数
    Long currentTimeMillis = System.currentTimeMillis();

    //活动有效时间
    Long expireTime = endTimeMillis - currentTimeMillis;
    if (currentTimeMillis < startTimeMillis){
        //活动未开始
        throw new ServiceException("活动未开始");
    }
    if (currentTimeMillis > endTimeMillis){
        //活动已结束
        throw new ServiceException("活动已结束");
    }
    //修改数据库中秒杀活动的状态
    activity.setStatus(1);
    this.updateById(activity);
    //开始预热操作
    //1.将活动信息保存到redis中
    Map activityMap = new HashMap<>();
    activityMap.put(SYS.SK_ACTIVITY_STATUS_HASH_KEY,1);
    activityMap.put(SYS.SK_ACTIVITY_START_TIME_KEY,startTimeMillis);
    activityMap.put(SYS.SK_ACTIVITY_END_TIME_KEY,endTimeMillis);
    redisTemplate.opsForHash().putAll(activity_redis_key,activityMap);
    redisTemplate.expire(activity_redis_key,expireTime, TimeUnit.MILLISECONDS);
    //2.将秒杀商品信息保存到redis中
    //获取数据库中的秒杀商品信息
    List<SeckillGoods> list = seckillGoodsService.getByActivityId(id); // 修改点
    for (SeckillGoods seckillGoods : list) {
        String product_redis_key = SYS.SK_PRE_PRODUCT_KEY + seckillGoods.getId();
        int sk_stock = seckillGoods.getStock();//秒杀库存
        redisTemplate.opsForValue().set(product_redis_key,sk_stock);
    }
    return true;
}

}
